﻿using System;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Media;
using LiveHub.DataModels;

namespace LiveHub.AvaloniaApp.Models;

public class MessagePanel : StackPanel
{
    protected override void OnDataContextChanged(EventArgs e)
    {
        base.OnDataContextChanged(e);
        if (DataContext is not MessageModel model) return;
        var lines = model.Body.Split(Environment.NewLine);
        var blocks = lines.Select(x => new BlockMessage(x)).ToArray();
        foreach (var blockMessage in blocks)
        {
            Children.Add(GetParagraph(blockMessage));
        }
    }

    private static TextBlock GetItalic(string text) => new() { Text = text, FontStyle = FontStyle.Italic };

    private static TextBlock GetUnderline(string text) => new()
    {
        Text = text,
        TextDecorations = new TextDecorationCollection() { new() { Location = TextDecorationLocation.Underline } }
    };

    private static TextBlock GetBold(string text) => new() { Text = text, FontWeight = FontWeight.SemiBold };

    private static TextBlock GetAt(string text) => new() { Text = text, Foreground = Brushes.DodgerBlue };

    private static WrapPanel GetParagraph(BlockMessage blockMessage)
    {
        var wrap = new WrapPanel();
        foreach (var item in blockMessage.Items)
        {
            switch (item)
            {
                case ItalicMessage italic:
                    wrap.Children.Add(GetItalic(italic.Content));
                    break;
                case UnderlineMessage underline:
                    wrap.Children.Add(GetUnderline(underline.Content));
                    break;
                case BoldMessage bold:
                    wrap.Children.Add(GetBold(bold.Content));
                    break;
                case AtMessage at:
                    wrap.Children.Add(GetAt(at.Content));
                    break;
                case StringMessage stringMessage:
                    wrap.Children.Add(new TextBlock { Text = stringMessage.Content });
                    break;
            }
        }

        return wrap;
    }
}